package cn.luckdou.WeChat.web;

import cn.luckdou.WeChat.Dispatcher.EventDispatcher;
import cn.luckdou.WeChat.config.WxMpConfig;
import cn.luckdou.system.service.we_chat_event.IWeChatEventService;
import cn.luckdou.WeChat.Dispatcher.MsgDispatcher;
import cn.luckdou.WeChat.utils.JsapiTicketUtils;
import cn.luckdou.WeChat.utils.MessageUtil;
import cn.luckdou.WeChat.utils.SignUtil;
import cn.luckdou.system.model.we_chat_event.WeChatEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Controller
@RequestMapping("/havezoneWechat")
public class WXController {
    @Autowired
    private IWeChatEventService weChatEventService;

    @GetMapping("")
    @ResponseBody
    public void hello(String signature, String echostr, String timestamp, String nonce, HttpServletResponse response){
        if (SignUtil.checkSignature(signature,timestamp,nonce)){
            this.write(response,echostr);
        }
    }

    @PostMapping("")
    public String post(@RequestBody String requestBody, String signature, String timestamp, String nonce,String openid,
                       HttpServletResponse response,HttpServletRequest request,
                       @RequestParam(name = "encrypt_type", required = false) String encType,
                       @RequestParam(name = "msg_signature", required = false) String msgSignature) {

        if (!SignUtil.checkSignature(signature, timestamp, nonce)) {
            throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
        }
        Map<String, String> map = MessageUtil.xmlToMap(requestBody);
        {
            //事件推送信息持久化到数据库(除上报地理位置事件外)
            WeChatEvent t = new WeChatEvent(map);
            if (!t.getType().equals("LOCATION")) weChatEventService.insert(t);
        }
        String s = null;
        if (!map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
            s = MsgDispatcher.processMessage(map); //进入普通消息分发处理器
        }else{
            s = EventDispatcher.processEvent(map,response);//进入事件消息分发处理器
        }
        this.write(response,s);
        return null;
    }

    private void write(HttpServletResponse response, String s){
        try {
            if (s==null || s.length()<=0) s="success";
            //这句话的意思，是告诉servlet用UTF-8转码，而不是用默认的ISO8859
            response.setHeader("Content-type", "text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            PrintWriter writer = response.getWriter();
            writer.write(s);
            writer.flush();
        }catch (Exception e){

        }
    }

    @PostMapping("/jsSdk")
    @ResponseBody
    public Map<String,Object> jsSdk(HttpServletRequest request,String url){
        //1.获取Ticket
        String jsapi_ticket = JsapiTicketUtils.getJsapiTicket();

        //2.随机字符串
        String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//随机字符串
        //3.时间戳
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//时间戳

        System.out.println("jsapi_ticket:"+jsapi_ticket+"\n时间戳："+timestamp+"\n随机字符串："+noncestr+"\nurl："+url);

        //4.获取url
//        String url=request.getRequestURL().toString();


        /*根据JSSDK上面的规则进行计算，这里比较简单，我就手动写啦
        String[] ArrTmp = {"jsapi_ticket","timestamp","nonce","url"};
        Arrays.sort(ArrTmp);
        StringBuffer sf = new StringBuffer();
        for(int i=0;i<ArrTmp.length;i++){
            sf.append(ArrTmp[i]);
        }
        */

        //5、将参数排序并拼接字符串
        String str = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;

        //6、将字符串进行sha1加密
        String signature =SignUtil.SHA1(str);

        System.out.println("参数："+str+"\n签名："+signature);


        HashMap<String, Object> map = new HashMap<>();
        map.put("appId", WxMpConfig.getAppid());
        map.put("timestamp",timestamp);
        map.put("nonceStr",noncestr);
        map.put("signature",signature);
        map.put("url",url);

        return map;

    }
}